#include <iostream>
#include <sw/redis++/redis.h>
#include <vector>
#include <sw/redis++/redis++.h>
#include <string>
#include <unordered_map>
#include "util.hpp"

using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::vector;
using std::unordered_map;
using sw::redis::Redis;

void test1(Redis& redis)
{
    cout << "set and get" << endl;
    redis.flushall();

    redis.set("key1", "111");
    auto value = redis.get("key1");
    if(value)
    {
        cout << "value: " << value.value() << endl;
    }

    redis.set("key1", "233");
    value = redis.get("key1");
    if(value)
    {
        cout << "value: " << value.value() << endl;
    }
}

void test2(Redis& redis)
{
    using namespace std::chrono_literals;
    cout << "set 设置定时" << endl;
    redis.flushall();

    redis.set("key1", "111", 10s);
    long long ttl = redis.ttl("key1");
    cout << ttl << endl;
}

void test3(Redis& redis)
{
    using namespace std::chrono_literals;
    cout << "set NX and XX" << endl;
    redis.flushall();

    redis.set("key1", "111", 0s, sw::redis::UpdateType::NOT_EXIST);
    auto value = redis.get("key1");
    if(value)
    {
        cout << "value: " << value.value() << endl;
    }

    redis.set("key1", "222", 0s, sw::redis::UpdateType::EXIST);
    value = redis.get("key1");
    if(value)
    {
        cout << "value: " << value.value() << endl;
    }

    redis.set("key1", "3333", 0s, sw::redis::UpdateType::NOT_EXIST);
    value = redis.get("key1");
    if(value)
    {
        cout << "value: " << value.value() << endl;
    }
}

void test4(Redis& redis)
{
    using namespace std::chrono_literals;
    cout << "mset and mget" << endl;
    redis.flushall();

    // redis.mset({std::make_pair("key1","2233"),std::make_pair("key2","3333"),std::make_pair("key3","444")});

    vector<std::pair<string,string>> keys{std::make_pair("key1","2233"),
        std::make_pair("key2","3333"),std::make_pair("key3","444")};

    redis.mset(keys.begin(), keys.end());

    vector<sw::redis::OptionalString> continer;
    auto it = std::back_inserter(continer);
    redis.mget({"key1", "key2", "key3", "key4"}, it);
    
    printContinerOption(continer);
}

void test5(Redis& redis)
{
    using namespace std::chrono_literals;
    cout << "getrange and setrange" << endl;
    redis.flushall();

    redis.set("key","abcdefghijklmn");

    string result = redis.getrange("key", 2, 5);
    cout << result << endl;

    redis.setrange("key", 2, "ccb");
    auto value = redis.get("key");
    if(value)
    {
        cout << value.value() << endl;
    }
}

void test6(Redis& redis)
{
    using namespace std::chrono_literals;
    cout << "incr and decr" << endl;
    redis.flushall();

    redis.set("key", "100");

    long long result = redis.incr("key");
    cout << result << endl;

    result = redis.decr("key");
    cout << result << endl;

}

int main()
{
    Redis redis("tcp://127.0.0.1:6379");
    // string result = redis.ping();
    // cout << result << endl;
    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    // test5(redis);
    test6(redis);
    return 0;
}